namespace html_entities
{
	typedef struct {
		const char* name;
		const wchar_t* meaning;
	} HTML_ENTITY_TRANSL;

	// source:
	// http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references

	static HTML_ENTITY_TRANSL entity_table[249] = {
		{ "nbsp", L" " },
		{ "iexcl", L"\x00A1" },
		{ "cent", L"\x00A2" },
		{ "pound", L"\x00A3" },
		{ "curren", L"\x00A4" },
		{ "yen", L"\x00A5" },
		{ "brvbar", L"\x00A6" },
		{ "sect", L"\x00A7" },
		{ "uml", L"\x00A8" },
		{ "copy", L"\x00A9" },
		{ "ordf", L"\x00AA" },
		{ "laquo", L"\x00AB" },
		{ "not", L"\x00AC" },
		{ "shy", L"\x00AD" },
		{ "reg", L"\x00AE" },
		{ "macr", L"\x00AF" },
		{ "deg", L"\x00B0" },
		{ "plusmn", L"\x00B1" },
		{ "sup2", L"\x00B2" },
		{ "sup3", L"\x00B3" },
		{ "acute", L"\x00B4" },
		{ "micro", L"\x00B5" },
		{ "para", L"\x00B6" },
		{ "middot", L"\x00B7" },
		{ "cedil", L"\x00B8" },
		{ "sup1", L"\x00B9" },
		{ "ordm", L"\x00BA" },
		{ "raquo", L"\x00BB" },
		{ "frac14", L"\x00BC" },
		{ "frac12", L"\x00BD" },
		{ "frac34", L"\x00BE" },
		{ "iquest", L"\x00BF" },
		{ "Agrave", L"\x00C0" },
		{ "Aacute", L"\x00C1" },
		{ "Acirc", L"\x00C2" },
		{ "Atilde", L"\x00C3" },
		{ "Auml", L"\x00C4" },
		{ "Aring", L"\x00C5" },
		{ "AElig", L"\x00C6" },
		{ "Ccedil", L"\x00C7" },
		{ "Egrave", L"\x00C8" },
		{ "Eacute", L"\x00C9" },
		{ "Ecirc", L"\x00CA" },
		{ "Euml", L"\x00CB" },
		{ "Igrave", L"\x00CC" },
		{ "Iacute", L"\x00CD" },
		{ "Icirc", L"\x00CE" },
		{ "Iuml", L"\x00CF" },
		{ "ETH", L"\x00D0" },
		{ "Ntilde", L"\x00D1" },
		{ "Ograve", L"\x00D2" },
		{ "Oacute", L"\x00D3" },
		{ "Ocirc", L"\x00D4" },
		{ "Otilde", L"\x00D5" },
		{ "Ouml", L"\x00D6" },
		{ "times", L"\x00D7" },
		{ "Oslash", L"\x00D8" },
		{ "Ugrave", L"\x00D9" },
		{ "Uacute", L"\x00DA" },
		{ "Ucirc", L"\x00DB" },
		{ "Uuml", L"\x00DC" },
		{ "Yacute", L"\x00DD" },
		{ "THORN", L"\x00DE" },
		{ "szlig", L"\x00DF" },
		{ "agrave", L"\x00E0" },
		{ "aacute", L"\x00E1" },
		{ "acirc", L"\x00E2" },
		{ "atilde", L"\x00E3" },
		{ "auml", L"\x00E4" },
		{ "aring", L"\x00E5" },
		{ "aelig", L"\x00E6" },
		{ "ccedil", L"\x00E7" },
		{ "egrave", L"\x00E8" },
		{ "eacute", L"\x00E9" },
		{ "ecirc", L"\x00EA" },
		{ "euml", L"\x00EB" },
		{ "igrave", L"\x00EC" },
		{ "iacute", L"\x00ED" },
		{ "icirc", L"\x00EE" },
		{ "iuml", L"\x00EF" },
		{ "eth", L"\x00F0" },
		{ "ntilde", L"\x00F1" },
		{ "ograve", L"\x00F2" },
		{ "oacute", L"\x00F3" },
		{ "ocirc", L"\x00F4" },
		{ "otilde", L"\x00F5" },
		{ "ouml", L"\x00F6" },
		{ "divide", L"\x00F7" },
		{ "oslash", L"\x00F8" },
		{ "ugrave", L"\x00F9" },
		{ "uacute", L"\x00FA" },
		{ "ucirc", L"\x00FB" },
		{ "uuml", L"\x00FC" },
		{ "yacute", L"\x00FD" },
		{ "thorn", L"\x00FE" },
		{ "yuml", L"\x00FF" },
		{ "OElig", L"\x0152" },
		{ "oelig", L"\x0153" },
		{ "Scaron", L"\x0160" },
		{ "scaron", L"\x0161" },
		{ "Yuml", L"\x0178" },
		{ "fnof", L"\x0192" },
		{ "circ", L"\x02C6" },
		{ "tilde", L"\x02DC" },
		{ "Alpha", L"\x0391" },
		{ "Beta", L"\x0392" },
		{ "Gamma", L"\x0393" },
		{ "Delta", L"\x0394" },
		{ "Epsilon", L"\x0395" },
		{ "Zeta", L"\x0396" },
		{ "Eta", L"\x0397" },
		{ "Theta", L"\x0398" },
		{ "Iota", L"\x0399" },
		{ "Kappa", L"\x039A" },
		{ "Lambda", L"\x039B" },
		{ "Mu", L"\x039C" },
		{ "Nu", L"\x039D" },
		{ "Xi", L"\x039E" },
		{ "Omicron", L"\x039F" },
		{ "Pi", L"\x03A0" },
		{ "Rho", L"\x03A1" },
		{ "Sigma", L"\x03A3" },
		{ "Tau", L"\x03A4" },
		{ "Upsilon", L"\x03A5" },
		{ "Phi", L"\x03A6" },
		{ "Chi", L"\x03A7" },
		{ "Psi", L"\x03A8" },
		{ "Omega", L"\x03A9" },
		{ "alpha", L"\x03B1" },
		{ "beta", L"\x03B2" },
		{ "gamma", L"\x03B3" },
		{ "delta", L"\x03B4" },
		{ "epsilon", L"\x03B5" },
		{ "zeta", L"\x03B6" },
		{ "eta", L"\x03B7" },
		{ "theta", L"\x03B8" },
		{ "iota", L"\x03B9" },
		{ "kappa", L"\x03BA" },
		{ "lambda", L"\x03BB" },
		{ "mu", L"\x03BC" },
		{ "nu", L"\x03BD" },
		{ "xi", L"\x03BE" },
		{ "omicron", L"\x03BF" },
		{ "pi", L"\x03C0" },
		{ "rho", L"\x03C1" },
		{ "sigmaf", L"\x03C2" },
		{ "sigma", L"\x03C3" },
		{ "tau", L"\x03C4" },
		{ "upsilon", L"\x03C5" },
		{ "phi", L"\x03C6" },
		{ "chi", L"\x03C7" },
		{ "psi", L"\x03C8" },
		{ "omega", L"\x03C9" },
		{ "thetasym", L"\x03D1" },
		{ "upsih", L"\x03D2" },
		{ "piv", L"\x03D6" },
		{ "ensp", L"\x2002" },
		{ "emsp", L"\x2003" },
		{ "thinsp", L"\x2009" },
		{ "zwnj", L"\x200C" },
		{ "zwj", L"\x200D" },
		{ "lrm", L"\x200E" },
		{ "rlm", L"\x200F" },
		{ "ndash", L"\x2013" },
		{ "mdash", L"\x2014" },
		{ "lsquo", L"\x2018" },
		{ "rsquo", L"\x2019" },
		{ "sbquo", L"\x201A" },
		{ "ldquo", L"\x201C" },
		{ "rdquo", L"\x201D" },
		{ "bdquo", L"\x201E" },
		{ "dagger", L"\x2020" },
		{ "Dagger", L"\x2021" },
		{ "bull", L"\x2022" },
		{ "hellip", L"\x2026" },
		{ "permil", L"\x2030" },
		{ "prime", L"\x2032" },
		{ "Prime", L"\x2033" },
		{ "lsaquo", L"\x2039" },
		{ "rsaquo", L"\x203A" },
		{ "oline", L"\x203E" },
		{ "frasl", L"\x2044" },
		{ "euro", L"\x20AC" },
		{ "image", L"\x2111" },
		{ "weierp", L"\x2118" },
		{ "real", L"\x211C" },
		{ "trade", L"\x2122" },
		{ "alefsym", L"\x2135" },
		{ "larr", L"\x2190" },
		{ "uarr", L"\x2191" },
		{ "rarr", L"\x2192" },
		{ "darr", L"\x2193" },
		{ "harr", L"\x2194" },
		{ "crarr", L"\x21B5" },
		{ "lArr", L"\x21D0" },
		{ "uArr", L"\x21D1" },
		{ "rArr", L"\x21D2" },
		{ "dArr", L"\x21D3" },
		{ "hArr", L"\x21D4" },
		{ "forall", L"\x2200" },
		{ "part", L"\x2202" },
		{ "exist", L"\x2203" },
		{ "empty", L"\x2205" },
		{ "nabla", L"\x2207" },
		{ "isin", L"\x2208" },
		{ "notin", L"\x2209" },
		{ "ni", L"\x220B" },
		{ "prod", L"\x220F" },
		{ "sum", L"\x2211" },
		{ "minus", L"\x2212" },
		{ "lowast", L"\x2217" },
		{ "radic", L"\x221A" },
		{ "prop", L"\x221D" },
		{ "infin", L"\x221E" },
		{ "ang", L"\x2220" },
		{ "and", L"\x2227" },
		{ "or", L"\x2228" },
		{ "cap", L"\x2229" },
		{ "cup", L"\x222A" },
		{ "int", L"\x222B" },
		{ "there4", L"\x2234" },
		{ "sim", L"\x223C" },
		{ "cong", L"\x2245" },
		{ "asymp", L"\x2248" },
		{ "ne", L"\x2260" },
		{ "equiv", L"\x2261" },
		{ "le", L"\x2264" },
		{ "ge", L"\x2265" },
		{ "sub", L"\x2282" },
		{ "sup", L"\x2283" },
		{ "nsub", L"\x2284" },
		{ "sube", L"\x2286" },
		{ "supe", L"\x2287" },
		{ "oplus", L"\x2295" },
		{ "otimes", L"\x2297" },
		{ "perp", L"\x22A5" },
		{ "sdot", L"\x22C5" },
		{ "lceil", L"\x2308" },
		{ "rceil", L"\x2309" },
		{ "lfloor", L"\x230A" },
		{ "rfloor", L"\x230B" },
		{ "lang", L"\x27E8" },
		{ "rang", L"\x27E9" },
		{ "loz", L"\x25CA" },
		{ "spades", L"\x2660" },
		{ "clubs", L"\x2663" },
		{ "hearts", L"\x2665" },
		{ "diams", L"\x2666" },
		{ NULL, NULL }
	};

	const wchar_t* translate(const char* entity_name)
	{
		for(int i = 0; entity_table[i].name != NULL; i++)
		{
			if(!_stricmp(entity_name, entity_table[i].name))
			{
				return entity_table[i].meaning;
			}
		}
		return NULL;
	}
};
